/**
 * ErrorBase.cpp
 *
 *  Description : Class to use as a base class for exception classes. It attaches the backtrace to the error message.
 */

#include "ErrorBase.hpp"

#include <sstream>
#include <execinfo.h>
#include <cstdlib>
#include <cstdio>

namespace btexc
{

namespace
{


/// Maximum backtrace length - how much back in stack backtrace to go
const unsigned int MAX_BACKTRACE_LENGTH = 10;

/**
 * Gets the stack backtrace.
 *
 * @param[in] errText string to put before the backtrace
 *
 * @return a string containing the error message, with backtrace attached to it
 *
 */
std::string GetCurrentBacktrace( const std::string& errText )
{
	std::stringstream ss;
	void *buffer[MAX_BACKTRACE_LENGTH];

	const int backtraceLen = backtrace( buffer, MAX_BACKTRACE_LENGTH );
	char **strings = backtrace_symbols( buffer, backtraceLen );

	if ( 0 != strings )
	{
		ss << errText << "\n";
		for ( int j = 0; j < backtraceLen; j++ )
		{
			ss << strings[j] << "\n";
		}
	}
	else
	{
		perror( "Error getting backtrace symbols." );
	}

	free( strings );

	return ss.str();
}

}

/**
 * Constructor
 *
 * @param[in] errText error message describing the error
 *
 */
ErrorBase::ErrorBase( const std::string& errText ) :
		std::runtime_error( GetCurrentBacktrace( errText ) )
{
}

} /* namespace btexc */

